_package("caf.ui");

_import("caf.mui.Component");
_import("caf.mui.ModalPanel");
_import("caf.ui.Page");
_import("caf.ui.DeckView");

/**
 * Page伪页面管理组件
 */
_class("DeckPage", DeckView, function(){
	this._init = function(){
		_super._init.call(this);
		this._app = null;          //所属应用对象
		this._modalPanel = null;   //模态蒙板
		this._conf = {};           //Page类配置信息
		this._history = null;      //历史记录管理
		this._backing = false;     //标识是否处在page回退过程中
		this._activePage = null;   //当前活动的Page页
		this._useAnimate = false;  //页面切换过程是否播放动画
		this._queue = [];          //页面切换动画队列
		this._busy = false;        //是否正在忙于动画播放
		this._busyTimer = 0;       //动画播放超市定时器
		this._lastTime = 0;
		this._lastPid = "";
	};
	this.create = function(parent, app, history){
		this.setParent(parent);
		this._app = app;
		this._history = history;
		var pages = this._app.findConf("page");
		for(var i = 0, len = pages.length; i < len; i++){
			var conf = pages[i];
			if(typeof conf.clazz == "string"){
				if(!(conf.clazz in __context__) || typeof __context__[conf.clazz] != "function"){
					runtime.error("[DeckPage::create]" + conf.clazz);
				}
				conf.clazz = __context__[conf.clazz];
			}
			if(!("flag" in conf)){
				conf.flag = 3;
			}
			this._conf[conf.pid] = conf;
			//for debug
			if(conf.flag != 2 && runtime._debugPane){
				runtime._debugPane.createPageListItem(conf, app);
			}
		}
		var obj = this.createElement(parent, "div", "wui-DeckPage");
		this.init(obj);
		return obj;
	};
	/**
	 * 重置到初始状态，需要删除所有的page组件
	 */
	this.reset = function(){
		_super.reset.apply(this);
		this._activePage = null;
		this._history.clear();
	};
	this.dispose = function(){
		runtime.stopTimer(this._busyTimer);
		for(var i = 0, len = this._queue.length; i < len; i++){
			this._queue[i] = null;
		}
		this._queue = [];
		this._activePage = null;
		this._history = null;
		for(var k in this._conf){
			delete this._conf[k];
		}
		if(this._modalPanel){
			this._modalPanel.dispose();
			this._modalPanel = null;  //模态对话框用的模态面板
		}
		this._app = null;
		_super.dispose.apply(this);
	};
	this.setUseAnimate = function(v){
		this._useAnimate = v;
	};
	this.getActivePage = function(){
		return this._activePage;
	};
	this.getPage = function(key){
		return this.getView(key);
	};
	/**
	 * 基于延迟创建的考虑
	 */
	this.getPage2 = function(key, params){
		var page;
		if(!this.exist(key)){
			page = this.createPage(null, key, params);
		}else{
			page = this.getView(key);
			page.setParams(params);
		}
		return page;
	};
	this.createPage = function(parent, key, params/*, html*/){
		parent = parent || this;  //runtime.getWorkspace()
		var k = key.split("#")[0];
		var conf = this._conf[k];
		var page = new conf.clazz();
		page.setApp(this._app);
		if(parent instanceof Page){
			page.setParentPage(parent);
		}
		page.setParams(params);
		//setData内部处理过了
		//page.setPid(conf.pid);
		//page.setTpl(conf.tpl);
		page.setData(conf);
		page.create(parent/*, html*/);
		this.pushItem1(key, page);
		return page;
	};
	this.removePage = function(key){
		if(key in this._hash){
			runtime.log("[DeckPage::removePage]key=" + key);
			this._hash[key].dispose();
			delete this._hash[key];
		}
	};
	this.getModalPanel = function(){
		if(!this._modalPanel){
			this._modalPanel = new ModalPanel();
			this._modalPanel.create(this);
			this._modalPanel.setVisible(false);
		}
		return this._modalPanel;
	};
	//this.goPage =
	/**
	 * Page对象导航(简单模拟页面导航功能)
	 * [TO-DO]需要将动画效果从该方法中独立出来
	 * @param {String} pid Page编号
	 * @param {Object} params 传递给page对象的参数
	 * @param {Number} offset 历史纪录偏移量，默认1
	 */
	this.navPage = function(pid, params, offset, agent, func){
		var time = new Date().getTime();
		if(time < this._lastTime + 1000 && this._lastPid == pid){
			this._lastTime = time;
			this._lastPid = pid;
			return;
		}
		this._lastTime = time;
		this._lastPid = pid;
		if(this._useAnimate){
			if(this._busy) return;
			this._busy = true;
			this._busyTimer = runtime.startTimer(2000, this, function(){
				if(this._busy){
					runtime.warning("[DeckPage::navPage]有超时动画存在");
					this._busy = false;
				}
			});  //动画应该在两秒钟内播放完毕
		}
		var argv = [];
		for(var i = 0, len = arguments.length; i < len; i++){
			argv.push(arguments[i]);
		}
		this._queue.push(argv);
		if(typeof offset == "undefined") offset = 1;
		var item = this._history.getItem(offset);  //没有传递params参数时，优先选择历史记录中的参数
		params = params || (item ? item.params : {});
		if(!("navmode" in params)){
			params["navmode"] = "normal";  //normal|modal|modeless|custom
		}
		//fixed: firefox,safari等浏览器下arguments不能同步实参重新赋值的问题
		argv[1] = params;
		argv[2] = offset;
		var page = this.getPage2(pid, params);
		var ev = {  //{PageChangeEvent}
			"type"  : "pageChange",
			"page0" : this._activePage,  //该参数可能为null
			"page"  : page,
			"offset": offset
		};
		if(params && params.async){
			page.load(params, this, function(json){
				//this.showArticle(json);
				params.json = json;
				this.onNavPage(ev, params);
			});
		}else{
			this.onNavPage(ev, params);
		}
	};
	this.onNavPage = function(ev, params){
		if(this._activePage){
			this._activePage.fireEvent({"type": "deactivate"});
		}
		/*
		 * ev参数格式: {type: "reset", params: {}}
		 */
		//ev.page.fireEvent({"type": "reset", "params": params});
		ev.page.reset(params);
		if(ev.offset < 0){  //退栈动作
			for(var i = 0, len = -ev.offset; i < len; i++){
				var pp = this.getPage(this._history.pop().pid);
				pp[this._useAnimate ? "onAnimateHide" : "onHide"]({  //[TODO]不需要播放动画，直接一步到位即可
					"type" : "pageChange",
					"page0": pp,
					"page" : ev.page
				});
			}
			ev.offset = 0;
		}
		/*
		var navmode0;
		if(this._activePage){
			navmode0 = this._history.getCurrent().params.navmode;
		}else{
			navmode0 = "";
		}
		*/
		var navmode0 = this._activePage ? this._history.getCurrent().params.navmode : "";
		var val = this.mapPageShow(navmode0, params.navmode);
		var _this = this;
		var view = this._activePage;
		this.fff = function(){
			if(view && val.charAt(0) == "#"){
				//delete ev.cbid;
				ev.cbid = runtime._task.add(this, "onNavEnd", [ev]);
				view[this._useAnimate ? "onAnimateHide" : "onHide"](ev);
			}else{
				this.onNavEnd(ev);
			}
		};
		if(val.charAt(1) == "#"){
			ev.cbid = runtime._task.add(this, "fff");
			ev.page[this._useAnimate ? "onAnimateShow" : "onShow"](ev);
		}else{
			this.fff();
		}
	};
	//navPage异步动画完成后的执行的方法
	this.onNavEnd = function(ev){
		delete ev.cbid;
		ev.page.fireEvent({"type": "activate"});
		this._activePage = ev.page;
		var obj = this._queue.shift();
		//obj[0] - pid
		//obj[1] - params
		//obj[2] - offset
		//obj[3] - agent
		//obj[4] - func
		if(obj[3]){  //有回调，说明是pageBack行为
			obj[4].call(obj[3]);
		}else{
			this._history.put({"pid": obj[0], "params": obj[1]}, ev.offset);  //更新历史记录
		}
		if(this._useAnimate){
			this._busy = false;
			runtime.stopTimer(this._busyTimer);
			if(this._queue.length > 0){
				this.navPage.apply(this, this._queue.shift());
			}
		}
	};
	this.pageBack = function(){
		var item = this._history.getPrevious();
		if(item){  //历史记录已经为空
			this._backing = true;
			//this.getPreviousPage().getPid()
			this.navPage(item.pid, item.params, 0, this, function(){
				this._history.pop();
			});
			this._backing = false;
		}
	};
	/**
	 * 显示模式说明
	 */
	this.mapPageShow = function(navmode0, navmode){
		/*
		var flag = page.getData().flag;
		if(this._activePage && params.navmode != "modal" && params.navmode != "modeless"){}
		if(!this._activePage                       //第一次navPage，还没有_activePage
			|| this._activePage.getData().flag != 3  //_activePage不是模态，意味着(之前的)page没有处于显示状态
			|| navmode == "modal"){  //flag == 3     //目标page是模态
			var n = 1;
		}
		*/
		var map = {
			"normal"  : 0,
			"custom"  : 1,
			"modeless": 2,
			"modal"   : 3
		};
		/*
		显示模式矩阵
		# 标识需要执行隐藏或显示动作
		- 标识不需要执行隐藏或显示动作
		*/
		var arr = [
			//            normal custom modeless modal   <-- page
			/*normal  */["##"  ,"##"  ,"-#"    ,"-#"],
			/*custom  */["##"  ,"##"  ,"-#"    ,"-#"],
			/*modeless*/["-#"  ,"-#"  ,"--"    ,"-#"],
			/*modal   */["-#"  ,"-#"  ,"-#"    ,"-#"],
			/*null    */["-#"  ,"-#"  ,"-#"    ,"-#"]
			//<-- this._activePage
		];
		var m = navmode0 ? map[navmode0] : 4;
		var n = map[navmode];
		var v = arr[m][n];
		return this._backing ? v.charAt(1) + v.charAt(0) : v;
	};
});